home *** CD-ROM | disk | FTP | other *** search
- //=--------------------------------------------------------------------------=
- // InvisibleCtl.Cpp
- //=--------------------------------------------------------------------------=
- // Copyright 1995 Microsoft Corporation. All Rights Reserved.
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //=--------------------------------------------------------------------------=
- //
- //
- //
- #include "IPServer.H"
-
- #include "Guids.H"
- #include "InvisibleCtl.H"
- #include "LocalObj.H"
- #include "Util.H"
- #include "Globals.H"
- #include "Resource.H"
-
- // for ASSERT and FAIL
- //
- SZTHISFILE
-
- // NOTE: passing the control pointer this way implies that there can only be one
- // instance of this control in a process, and generally is a pretty bad
- // way of doing things. however, it's convenient, and serves our purposes
- // for this sample.
- //
- static CInvisibleControl *s_pCtl;
-
- //=--------------------------------------------------------------------------=
- // for persistence
- //
- #define STREAMHDR_MAGIC 0x12345678
-
- typedef struct {
-
- DWORD dwMagic;
- DWORD dwVersion;
- DWORD cbSize;
-
- } STREAMHDR;
-
- WCHAR wszTimeOut [] = L"TimeOut";
-
-
-
-
- //=--------------------------------------------------------------------------=
- // all the events in this control
- //
- typedef enum {
- InvisibleEvent_Time = 0
- } INVISIBLEVENTS;
-
- EVENTINFO m_rgEvents [] = {
- { DISPIDE_TIME, 0, NULL }
- };
-
- //=--------------------------------------------------------------------------=
- // array describing all of our property pages. these clsids are typically
- // in guids.h
- //
- // TODO: add any additional property page guids here ...
- //
- const GUID *rgInvisiblePropPages [] = {
- &CLSID_InvisibleGeneralPage
- };
-
- //=--------------------------------------------------------------------------=
- // Custum Verb information
- //
- // TODO: add any custom verbs here in an array, using the VERBINFO structure.
- // then mark the controld def'n in InvisibleCtl.H with
- // this verb array
- //
-
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::Create
- //=--------------------------------------------------------------------------=
- // global static function that creates an instance of the control an returns
- // an IUnknown pointer for it.
- //
- // Parameters:
- // IUnknown * - [in] controlling unknown for aggregation
- //
- // Output:
- // IUnknown * - new object.
- //
- // Notes:
- //
- IUnknown *CInvisibleControl::Create
- (
- IUnknown *pUnkOuter
- )
- {
- // make sure we return the private unknown so that we support aggegation
- // correctly!
- //
- CInvisibleControl *pNew = new CInvisibleControl(pUnkOuter);
- return pNew->PrivateUnknown();
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::CInvisibleControl
- //=--------------------------------------------------------------------------=
- // "Being born is like being kidnapped. And then sold into slavery."
- // - andy warhol (1928 - 87)
- //
- // Parameters:
- // IUnknown * - [in]
- //
- // Notes:
- //
- #pragma warning(disable:4355) // using 'this' in constructor
- CInvisibleControl::CInvisibleControl
- (
- IUnknown *pUnkOuter
- )
- : COleControl(pUnkOuter, OBJECT_TYPE_CTLINVISIBLE, (IDispatch *)this)
- {
-
- memset(&m_state, 0, sizeof(INVISIBLECTLSTATE));
-
- // set default time out ot 1 second.
- //
- m_state.lTimeOut = 1;
- m_fTimer = FALSE;
- m_hIcon = NULL;
- }
- #pragma warning(default:4355) // using 'this' in constructor
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::~CInvisibleControl
- //=--------------------------------------------------------------------------=
- // "We all labour against our own cure, for death is the cure of all diseases"
- // - Sir Thomas Browne (1605 - 82)
- //
- // Notes:
- //
- CInvisibleControl::~CInvisibleControl ()
- {
- // TODO: clean up anything here.
- if (m_fTimer)
- KillTimer(NULL, 666);
-
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl:RegisterClassData
- //=--------------------------------------------------------------------------=
- // register the window class information for your control here.
- // this information will automatically get cleaned up for you on DLL shutdown.
- //
- // Output:
- // BOOL - FALSE means fatal error.
- //
- // Notes:
- //
- BOOL CInvisibleControl::RegisterClassData
- (
- void
- )
- {
- FAIL("This doesn't get called for InvisibleAtRuntime controls!");
- return FALSE;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::InternalQueryInterface
- //=--------------------------------------------------------------------------=
- // qi for things only we support.
- //
- // Parameters:
- // Parameters:
- // REFIID - [in] interface they want
- // void ** - [out] where they want to put the resulting object ptr.
- //
- // Output:
- // HRESULT - S_OK, E_NOINTERFACE
- //
- // Notes:
- //
- HRESULT CInvisibleControl::InternalQueryInterface
- (
- REFIID riid,
- void **ppvObjOut
- )
- {
- IUnknown *pUnk;
-
- *ppvObjOut = NULL;
-
- // TODO: if you want to support any additional interrfaces, then you should
- // indicate that here. never forget to call COleControl's version in the
- // case where you don't support the given interface.
- //
- if (DO_GUIDS_MATCH(riid, IID_IInvisible)) {
- pUnk = (IUnknown *)(IInvisible *)this;
- } else{
- return COleControl::InternalQueryInterface(riid, ppvObjOut);
- }
-
- pUnk->AddRef();
- *ppvObjOut = (void *)pUnk;
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::LoadTextState
- //=--------------------------------------------------------------------------=
- // load in our text state for this control.
- //
- // Parameters:
- // IPropertyBag * - [in] property bag to read from
- // IErrorLog * - [in] errorlog object to use with proeprty bag
- //
- // Output:
- // HRESULT
- //
- // Notes:
- // - NOTE: if you have a binary object, then you should pass an unknown
- // pointer to the property bag, and it will QI it for IPersistStream, and
- // get said object to do a Load()
- //
- STDMETHODIMP CInvisibleControl::LoadTextState
- (
- IPropertyBag *pPropertyBag,
- IErrorLog *pErrorLog
- )
- {
- VARIANT v;
- HRESULT hr;
-
- v.vt = VT_I4;
- v.lVal = 0;
-
- // load in the TimeOut property. nothing terribly serious. we ignore any
- // failure so that if it can't be found, we just use the default of 1 sec.
- //
- hr = pPropertyBag->Read(wszTimeOut, &v, pErrorLog);
- if (SUCCEEDED(hr)) m_state.lTimeOut = v.lVal;
-
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::LoadBinaryState
- //=--------------------------------------------------------------------------=
- // loads in our binary state using streams.
- //
- // Parameters:
- // IStream * - [in] stream to write to.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CInvisibleControl::LoadBinaryState
- (
- IStream *pStream
- )
- {
- STREAMHDR sh;
- HRESULT hr;
-
- // first read in the streamhdr, and make sure we like what we're getting
- //
- hr = pStream->Read(&sh, sizeof(sh), NULL);
- RETURN_ON_FAILURE(hr);
-
- // sanity check
- //
- if (sh.dwMagic != STREAMHDR_MAGIC || sh.cbSize != sizeof(m_state))
- return E_UNEXPECTED;
-
- // read in the control state information
- //
- hr = pStream->Read(&(m_state), sizeof(m_state), NULL);
- RETURN_ON_FAILURE(hr);
-
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::SaveTextState
- //=--------------------------------------------------------------------------=
- // saves out the text state for this control using a property bag.
- //
- // Parameters:
- // IPropertyBag * - [in] the property bag with which to work.
- // BOOL - [in] if TRUE, then write out ALL properties, even
- // if they're their the default value ...
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CInvisibleControl::SaveTextState
- (
- IPropertyBag *pPropertyBag,
- BOOL fWriteDefaults
- )
- {
- HRESULT hr;
- VARIANT v;
-
- v.vt = VT_I4;
- v.lVal = m_state.lTimeOut;
-
- // save out the TimeOut property if it's not it's default value.
- //
- if ((m_state.lTimeOut != 1) || fWriteDefaults)
- hr = pPropertyBag->Write(wszTimeOut, &v);
-
- return hr;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::SaveBinaryState
- //=--------------------------------------------------------------------------=
- // save out the binary state for this control, using the given IStream object.
- //
- // Parameters:
- // IStream * - [in] save to which you should save.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- // - it is important that you seek to the end of where you saved your
- // properties when you're done with the IStream.
- //
- STDMETHODIMP CInvisibleControl::SaveBinaryState
- (
- IStream *pStream
- )
- {
- STREAMHDR sh = { STREAMHDR_MAGIC, MAKELONG(1, 0), sizeof(m_state) };
- HRESULT hr;
-
- // write out the stream hdr.
- //
- hr = pStream->Write(&sh, sizeof(sh), NULL);
- RETURN_ON_FAILURE(hr);
-
- // write out he control state information
- //
- hr = pStream->Write(&m_state, sizeof(m_state), NULL);
- return hr;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::OnSetExtent
- //=--------------------------------------------------------------------------=
- // called whenever we're about to resize the puppy.
- //
- // Parameters:
- // SIZEL * - [in] new desired size.
- //
- // Output:
- // BOOL - FALSE means we want a different size than that passed in.
- //
- // Notes:
- //
- BOOL CInvisibleControl::OnSetExtent
- (
- SIZEL *pSize
- )
- {
- // set up our initial size ... + 6 so we can have raised edge
- //
- m_Size.cx = 6 + GetSystemMetrics(SM_CXICON);
- m_Size.cy = 6 + GetSystemMetrics(SM_CYICON);
-
- return FALSE;
- }
-
- //=--------------------------------------------------------------------------=
- // _TimerProc
- //=--------------------------------------------------------------------------=
- //
- void CALLBACK _TimerProc
- (
- HWND hwnd,
- UINT uMsg,
- UINT idTimer,
- DWORD dwTime
- )
- {
- ASSERT(s_pCtl, "Maggots!");
-
- s_pCtl->FireEvent(&(m_rgEvents[InvisibleEvent_Time]));
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::FreezeEvents [IOleControl]
- //=--------------------------------------------------------------------------=
- // allows a container to freeze all of a controls events. when events are
- // frozen, a control will not fire any of them.
- //
- // Parameters:
- // BOOL - [in] TRUE means FREEZE, FALSE means THAW
- //
- // Output:
- // HRESULT - S_OK
- //
- // Notes:
- // - we maintain an internal count of freezes versus thaws.
- //
- STDMETHODIMP CInvisibleControl::FreezeEvents
- (
- BOOL fFreeze
- )
- {
- // if we're not in design mode, go and create the timer callback
- // sucker!
- //
- if (m_fTimer) {
- KillTimer(NULL, 666);
- m_fTimer = FALSE;
- s_pCtl = NULL;
- }
- if (m_state.lTimeOut) {
- m_fTimer = TRUE;
- SetTimer(NULL, 666, m_state.lTimeOut * 1000, (TIMERPROC)_TimerProc);
- s_pCtl = this;
- }
-
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::OnDraw
- //=--------------------------------------------------------------------------=
- // "I don't very much enjoy looking at paintings in general. i know too
- // much about them. i take them apart."
- // - georgia o'keeffe (1887-1986)
- //
- // Parameters:
- // HDC - [in] HDC to draw to
- // LPCRECTL - [in] rect we're drawing to
- // LPCRECTL - [in] window extent and origin for meta-files
- // HDC - [in] HIC for target device
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- HRESULT CInvisibleControl::OnDraw
- (
- HDC hdcDraw,
- LPCRECTL prcBounds,
- LPCRECTL prcWBounds,
- HDC hicTargetDevice
- )
- {
- if (!m_hIcon)
- m_hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_INVISIBLEICON));
-
- DrawEdge(hdcDraw, (LPRECT)(LPCRECT)prcBounds, EDGE_RAISED, BF_RECT | BF_MIDDLE);
-
- if (m_hIcon)
- DrawIcon(hdcDraw, prcBounds->left + 3, prcBounds->top + 3, m_hIcon);
-
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::WindowProc
- //=--------------------------------------------------------------------------=
- // window procedure for this control. nothing terribly exciting.
- //
- // Parameters:
- // see win32sdk on window procs.
- //
- // Notes:
- //
- LRESULT CInvisibleControl::WindowProc
- (
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- // TODO: handle any messages here, like in a normal window
- // proc. note that for special keys, you'll want to override and
- // implement OnSpecialKey.
- //
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::AboutBox
- //=--------------------------------------------------------------------------=
- // prints up an about box. fweeeee.
- //
- // Notes:
- //
- void CInvisibleControl::AboutBox
- (
- void
- )
- {
- // TODO: Ideally, one would use DialogBox, and some sort of Dialog Box here if
- // they wanted a slightly more interesting About Box ... you should
- // still call ModalDialog first, however.
- //
- ModalDialog(TRUE);
- MessageBox(NULL, "This is My Control", "About Invisible", MB_OK | MB_TASKMODAL);
- ModalDialog(FALSE);
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::get_TimeOut [IInvisible]
- //=--------------------------------------------------------------------------=
- // returns current time out value
- //
- // Parameters:
- // long * - [out] value is in seconds.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CInvisibleControl::get_TimeOut
- (
- long *plTimeOut
- )
- {
- CHECK_POINTER(plTimeOut);
- *plTimeOut = m_state.lTimeOut;
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CInvisibleControl::put_TimeOut [IInvisible]
- //=--------------------------------------------------------------------------=
- // sets current timeout
- //
- // Parameters:
- // long - [in] value is in seconds.
- //
- // Output:
- // HRESULT
- //
- // Notes:
- //
- STDMETHODIMP CInvisibleControl::put_TimeOut
- (
- long lTimeOut
- )
- {
- if (lTimeOut == m_state.lTimeOut)
- return S_OK;
-
- m_state.lTimeOut = lTimeOut;
-
- // clean ou the old dude first!
- //
- if (m_fTimer) {
- KillTimer(NULL, 666);
- m_fTimer = FALSE;
- s_pCtl = NULL;
- }
-
- if (m_state.lTimeOut) {
-
- // create a new timer.
- //
- m_fTimer = TRUE;
- SetTimer(NULL, 666, m_state.lTimeOut * 1000, (TIMERPROC)_TimerProc);
- s_pCtl = this;
- }
-
- // be-de-be-de-be-de-be-de that's all folks!
- //
- PropertyChanged(DISPID_TIMEOUT);
- m_fDirty = TRUE;
- return S_OK;
- }
-
-
-